import 'dart:io';

import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'log_utils.dart';

/// 网络请求工具
/// 官方文档 https://pub.flutter-io.cn/packages/http
class HttpUtil {
  /// package:http/retry.dart provides a class RetryClient to wrap an underlying http.Client which transparently retries failing requests.
  /// By default, this retries any request whose response has status code 503 Temporary Failure up to three retries.
  /// It waits 500ms before the first retry, and increases the delay by 1.5x each time.
  /// All of this can be customized using the RetryClient() constructor.
  static final client = RetryClient(http.Client());
  static const Map<String, String> header = const {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  };

  /// get请求
  ///
  /// [url] 请求的网址
  ///
  /// [headers] 请求头
  ///
  /// [onSuccess(Object object)]网络请求成功回调 object是 response.body
  ///
  /// [onFail(int statusCode, Object object)]网络请求失败回调
  static void get(
      {@required String? url,
      Map<String, String> headers = header,
      void onSuccess(Object object)?,
      void onFail(int statusCode, Object object)?}) async {
    try {
      var response = await client.get(Uri.parse(url!), headers: headers);
      if (response.statusCode == HttpStatus.ok) {
        if (onSuccess != null) {
          onSuccess(response.body);
        }
      } else {
        if (onFail != null) {
          onFail(response.statusCode, response.body);
        }
      }
      MyLog.i(
          """ get请求\n url: $url \n state: ${response.statusCode}\n response.body: ${response.body}""");
    } on Exception catch (e) {
      Fluttertoast.showToast(msg: "网络请求错误：${e.toString()}");
      MyLog.e("网络请求错误：${e.toString()}");
    }
  }

  ///post 请求
  ///[onSuccess(Object object)] 网络请求成功回调 @object 传出去的是response.body
  ///[onFail] 网络请求失败回调
  static void post(
      {@required String? url,
      Map<String, String> headers = header,
      @required Object? body,
      void onSuccess(Object response)?,
      void onFail(int statusCode, Object response)?}) async {
    try {
      var response = await client.post(
        Uri.parse(url!),
        headers: headers,
        body: JsonUtil.encodeObj(body),
      );
      if (response.statusCode == HttpStatus.ok) {
        if (onSuccess != null) {
          onSuccess(response.body);
        }
      } else {
        if (onFail != null) {
          onFail(response.statusCode, response.body);
        }
      }
    } on Exception catch (e) {
      Fluttertoast.showToast(msg: "网络请求错误：${e.toString()}");
      MyLog.e("网络请求错误：${e.toString()}");
    }
  }
}

///服务器返回的[response.body] 模型
///{"code":1,"message":"成功",
///"data":{"id":13303,"userName":"face_hj","departmentId":2,"sysName":"人脸识别云平台",
///"token":"eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJDWUtKIiwiZXhwIjoxNjIxNTExMjkyLCJ4LXVzZXJJZCI6MTMzMDN9.jWLtoGah7tPukLkRq5FzdnLOfAqX_WR-0MRef3y2GC4",
///"time":1621489692819,"type":97,"remark":null,"departmentTypeId":null,"creatTime":1618561825000,
///"departmentType":1,"cloudBillingFlag":0}}
class ResponseModel {
  int? code;
  String? message;
  ResponseData? data;

  ResponseModel(this.code, this.message, {this.data});

  ResponseModel.fromMap(Map map) {
    code = map["code"];
    message = map["message"];
    data!.id = map['id'];
    data!.userName = map['userName'];
    data!.departmentId = map['departmentId'];
    data!.sysName = map['sysName'];
    data!.token = map['token'];
    data!.time = map['time'];
    data!.type = map['type'];
    data!.remark = map['remark'];
    data!.departmentId = map['departmentId'];
    data!.createTime = map['createTime'];
    data!.departmentType = map['departmentType'];
    data!.cloudBillingFlag = map['cloudBillingFlag'];
  }

  Map toMap() {
    var map = {"code": code, "message": message, "data": data};
    return map;
  }
}

///服务器返回的数据[response.body] 中的 data 模型
class ResponseData {
  int id;
  String userName;
  int departmentId;
  String sysName;
  String token;
  int time;
  int type;
  String remark;
  int departmentTypeId;
  int createTime;
  int departmentType;
  int cloudBillingFlag;

  ResponseData(
      this.id,
      this.userName,
      this.departmentId,
      this.sysName,
      this.token,
      this.time,
      this.type,
      this.remark,
      this.departmentTypeId,
      this.createTime,
      this.departmentType,
      this.cloudBillingFlag);

  ResponseData.fromJson(Map<String, dynamic> map)
      : id = map['id'],
        userName = map['userName'],
        departmentId = map['departmentId'],
        sysName = map['sysName'],
        token = map['token'],
        time = map['time'],
        type = map['type'],
        remark = map['remark'],
        departmentTypeId = map['departmentTypeId'],
        createTime = map['createTime'],
        departmentType = map['departmentType'],
        cloudBillingFlag = map['cloudBillingFlag'];
}
